//给你一个字符串 word。如果 word 中同时存在某个字母的小写形式和大写形式，则称这个字母为 特殊字母 。 
//
// 返回 word 中 特殊字母 的数量。 
//
// 
//
// 示例 1: 
//
// 
// 输入：word = "aaAbcBC" 
// 
//
// 输出：3 
//
// 解释： 
//
// word 中的特殊字母是 'a'、'b' 和 'c'。 
//
// 示例 2: 
//
// 
// 输入：word = "abc" 
// 
//
// 输出：0 
//
// 解释： 
//
// word 中不存在大小写形式同时出现的字母。 
//
// 示例 3: 
//
// 
// 输入：word = "abBCab" 
// 
//
// 输出：1 
//
// 解释： 
//
// word 中唯一的特殊字母是 'b'。 
//
// 
//
// 提示： 
//
// 
// 1 <= word.length <= 50 
// word 仅由小写和大写英文字母组成。 
// 
//
// Related Topics 哈希表 字符串 👍 2 👎 0


package LeetCode.editor.cn;


import java.util.Arrays;

/**
 * @author ldltd
 * @date 2024-12-03 12:23:28
 * @description 3120.统计特殊字母的数量 I
 
 */
 
public class CountTheNumberOfSpecialCharactersI {
    public static void main(String[] args) {
    //测试代码
    CountTheNumberOfSpecialCharactersI fun = new CountTheNumberOfSpecialCharactersI();
    Solution solution= fun.new Solution();
        System.out.println('e'&31);
        System.out.println(1<<('e'&31));

    }

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
        public int numberOfSpecialChars(String word) {
            int[] mask = new int[2];
            /*
            *
            对于大写英文字母：其二进制从右往左第 6 个比特值一定是 0。
            对于小写英文字母：其二进制从右往左第 6 个比特值一定是 1。
            对于任何英文字母：其小写字母二进制低 5 位，一定和其大写字母二进制低 5 位相等。
            'a' 的 ASCII 码值是 97，二进制表示为 01100001。
            'A' 的 ASCII 码值是 65，二进制表示为 01000001。
            它们的二进制表示的最高位之间的区别就是 32，即 2^5，这是因为 ASCII 编码中大小写字母之间相差的固定值。
            * */
            for (char c : word.toCharArray()) {
                //c >> 5 & 1,计算从右往左第六位是不是1，如果是1说明是小写
                //1 << (c & 31)   ,   c & 31计算，低五位和c的&，得到这是第几个字母，再1<<。得到二级制
                //最后左边|右边，就可以标识每一个位上这个字母是否存在，其中mask[0]标识的是大写，mask[1]标识的是小写
                mask[c >> 5 & 1] |= 1 << (c & 31);
            }
            //Integer.bicCount计算一个整数中1的个数，把两个标识数字&，得到最后的结果
            return Integer.bitCount(mask[0] & mask[1]);
        }

    public int numberOfSpecialChars1(String word) {
        int[] map = new int[123];
        for (int i = 0; i < word.length(); i++) {
            //记录每个字母出现次数
            map[word.charAt(i)]++;
        }
        int ans = 0;
        for (int i = 0; i <= 90; i++) {
            //直接计算
            ans = (map[i] != 0 && map[i + 32] != 0) ? ans + 1 : ans;
        }
        return ans;
    }

}
//leetcode submit region end(Prohibit modification and deletion)

}
